package jp.co.menox.tmserver.dao;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.slim3.datastore.Datastore;

import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.Query;
import com.google.appengine.api.datastore.Query.SortDirection;

import jp.co.menox.tmcommon.meta.LendingMeta;
import jp.co.menox.tmcommon.model.Category;
import jp.co.menox.tmcommon.model.Lending;

/**
 * 貸したいものテーブル用dao
 * @author
 *
 */
public class LendingDao extends TmServerDaoBase<Lending>{

    private String nameOfCategoryId;
    private String nameOfUserId;
    private String nameOfWasDeleted;
    private String nameOfCreated;
    private String nameOfLendingId;
    protected Map<Long, String> lendingNameMap = null;
    protected Map<Long, String> lendingCommentMap = null;
    protected Map<Long, String> lendingCategoryMap = null;

    {
        LendingMeta meta = LendingMeta.get();
        nameOfCategoryId = meta.categoryId.getName();
        nameOfUserId = meta.userId.getName();
        nameOfWasDeleted = meta.wasDeleted.getName();
        nameOfCreated = meta.created.getName();
        nameOfLendingId = meta.id.getName();
    }


    // **** 使用中チェック（マスタ編集用）

    /*
     * categoryIdから該当するレコード件数を取得する（有効なもの）。
     * @param categoryId
     * @return 
     */
    public int getSizeInCategoryId(long categoryId) {
        List<Key> result = query()
                .filter(nameOfCategoryId, Query.FilterOperator.EQUAL, categoryId)
                .filter(nameOfWasDeleted, Query.FilterOperator.EQUAL, false)
                .sort(nameOfCreated, SortDirection.DESCENDING)
                .asKeyList();
        if (result == null) {
            return 0;
        }
        return result.size();
    }
    
    /*
     * userIdから該当するレコード件数を取得する（有効なもの）。
     * @param userId
     * @return 
     */
    public int getSizeInUserId(long userId) {
        // TODO: 設計次第　期限が切れたものは無効扱いすべきか
        List<Key> result = query()
                .filter(nameOfUserId, Query.FilterOperator.EQUAL, userId)
                .filter(nameOfWasDeleted, Query.FilterOperator.EQUAL, false)
                .sort(nameOfCreated, SortDirection.DESCENDING)
                .asKeyList();
        if (result == null) {
            return 0;
        }
        return result.size();
    }
    

    // **** サンプルメソッド
    
    /*
     * カテゴリIDから該当するレコードを取得する（有効なもの）。<br />
     * 使用は非推奨：　他の検索条件やページャ件数もあるのでこのqueryでは完結しない。
     * @param categoryId
     * @return 
     */
    @Deprecated
    public List<Lending> getAllInCategory(long categoryId) {
        List<Lending> result = query()
                .filter(nameOfCategoryId, Query.FilterOperator.EQUAL, categoryId)
                .filter(nameOfWasDeleted, Query.FilterOperator.EQUAL, false)
                .sort(nameOfCreated, SortDirection.DESCENDING)
                .asList();
        if (result == null) {
            return new ArrayList<Lending>();
        }
        return result;
    }
    
    /*
     * 貸与者IDから該当するレコードを取得する（有効なもの）。<br />
     * 使用は非推奨：　他の検索条件やページャ件数もあるのでこのqueryでは完結しない。
     * @param userId
     * @return 
     */
    @Deprecated
    public List<Lending> getAllInUserId(long userId) {
        List<Lending> result = query()
                .filter(nameOfUserId, Query.FilterOperator.EQUAL, userId)
                .filter(nameOfWasDeleted, Query.FilterOperator.EQUAL, false)
                .sort(nameOfCreated, SortDirection.DESCENDING)
                .asList();
        if (result == null) {
            return new ArrayList<Lending>();
        }
        return result;
    }
    
    /**
     * ID-品物名をmap形式で取得する
     * @return
     */
    public Map<Long, String> getLendingNameMap() {
        if (this.lendingNameMap != null) {
            // すでに取得済み
            return this.lendingNameMap;
        }

        this.lendingNameMap = new HashMap<Long, String>();
        List<Lending> modelList = getAll();
        if (modelList == null) {
            return this.lendingNameMap;
        }
        // mapに詰め替え
        for (Lending model: modelList) {
            this.lendingNameMap.put(Long.valueOf(model.getId()), model.getName());
        }
        
        return this.lendingNameMap;
    }
    /**
     * ID-貸出者コメントmap形式で取得する
     * @return
     */
    public Map<Long, String> getLendingCommentMap() {
        if (this.lendingCommentMap != null) {
            // すでに取得済み
            return this.lendingCommentMap;
        }

        this.lendingCommentMap = new HashMap<Long, String>();
        List<Lending> modelList = getAll();
        if (modelList == null) {
            return this.lendingCommentMap;
        }
        // mapに詰め替え
        for (Lending model: modelList) {
            this.lendingCommentMap.put(Long.valueOf(model.getId()), model.getComment());
        }
        
        return this.lendingCommentMap;
    }
    /**
     * ID-カテゴリIDをmap形式で取得する
     * @return
     */
    public Map<Long, String> getLendingCategoryMap() {
        if (this.lendingCategoryMap != null) {
            // すでに取得済み
            return this.lendingCategoryMap;
        }

        this.lendingCategoryMap = new HashMap<Long, String>();
        List<Lending> modelList = getAll();
        if (modelList == null) {
            return this.lendingCategoryMap;
        }
        // mapに詰め替え
        CategoryDao cDao = null;
        Map<Long, String> map = null;
        String categoryName = null;
        for (Lending model: modelList) {
            cDao = new CategoryDao();
            map = cDao.getCategoryMap();
            categoryName = map.get(model.getCategoryId());
            this.lendingCategoryMap.put(Long.valueOf(model.getId()), categoryName);
        }
        
        return this.lendingCategoryMap;
    }
}
